﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using DatastoreLib;
using ElevatorLib;
using TwitterLib;
using System.Threading;

namespace MainGUI
{
    public partial class MainWindow : Form
    {
        #region Declarations

        private AbstractElevatorFacade abstractElevator;
        private TwitterLib.Twitter tw;
        private SerialPort port;
        private static MainWindow form;

		ElevatorFeedbackImplementation ef;
        StorageImplementation st;

        #endregion
        
        #region Constructor + Debugwriter
        public MainWindow()
        {
            form = this;

            InitializeComponent();

            foreach (string str in SerialPort.GetPortNames())
                cmbPorts.Items.Add(str);

            ef = new ElevatorFeedbackImplementation();
            ef.TwitterNotification += new ElevatorFeedbackImplementation.TwitterNotificationHandler(SendTwitterMessage);

            st = new StorageImplementation();
            tw = new TwitterLib.Twitter();
            tw.TwitterMessageReceived += new Twitter.TwitterMessageHandler(SendRS232Message);
            aantalKeer();
            noodstopcount();
            Thread updaterThread = new Thread(new ThreadStart(renewer));
            updaterThread.IsBackground = true; 
            updaterThread.Start();
        }

        private void renewer()
        {
            while (true)
            {
                renewCurrentTab();
                Thread.Sleep(500);
            }
        }

        private static MainWindow GetForm()
        {
            return form;
        }

        private void WriteDebugMessage(String message)
        {
            /*lock (txtDebug)
            {
                this.txtDebug.Text += message + "\r\n";
            }*/
        }
        public static void WriteDebug(String message)
        {
            MainWindow.GetForm().WriteDebugMessage(message);
        }
        #endregion

        #region RS232 port + Elevator Controls
        private void btnStartRS232_Click(object sender, EventArgs e)
        {
            try
            {
                if (cmbPorts.Text.Length == 0)
                {
                    throw new Exception("Geen COM-poort geselecteerd.");
                }

                this.port = new SerialPort();

                port.PortName = cmbPorts.Text;
                port.BaudRate = 9600;
                port.Parity = (Parity)Enum.Parse(typeof(Parity), "None");
                port.StopBits = (StopBits)Enum.Parse(typeof(StopBits), "One");
                port.DataBits = 8;

               // port.DataReceived += new SerialDataReceivedEventHandler(rs232_DataReceived);

                abstractElevator = new AbstractElevatorImplementation(port,ef);

                MainWindow.WriteDebug("Succesfully opened RS232 port");
            }
            catch (Exception ex)
            {
                MainWindow.WriteDebug(ex.Message);
            }
        }

        void rs232_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int b = this.port.ReadByte();
            MessageBox.Show(b.ToString() + " which is converted to " + ((byte)b));
        }

        private void btnFloor1_Click_1(object sender, EventArgs e)
        {
            try
            {
                abstractElevator.GoTo(0);
            }
            catch (Exception ex)
            {
                MainWindow.WriteDebug("RS232-port niet geselecteerd. "+ex.Message);
            }
        }

        private void btnFloor2_Click(object sender, EventArgs e)
        {
            try
            {
                abstractElevator.GoTo(1);
            }
            catch (Exception ex)
            {
                MainWindow.WriteDebug("RS232-port niet geselecteerd. "+ex.Message);
            }
        }

        private void btnFloor3_Click(object sender, EventArgs e)
        {
            try
            {
                abstractElevator.GoTo(2);
            }
            catch (Exception ex)
            {
                MainWindow.WriteDebug("RS232-port niet geselecteerd. " + ex.Message);
            }
        }

        private void btnFloor4_Click(object sender, EventArgs e)
        {
            try
            {
                abstractElevator.GoTo(3);
            }
            catch (Exception ex)
            {
                MainWindow.WriteDebug("RS232-port niet geselecteerd. " + ex.Message);
            }
        }

        private void btnEmergency_Click(object sender, EventArgs e)
        {
            try
            {
                abstractElevator.CallEmergency(); 
            }
            catch (Exception ex)
            {
                MainWindow.WriteDebug("RS232-port niet geselecteerd. " + ex.Message);
            }
        }

        private void btnResumeOperations_Click(object sender, EventArgs e)
        {
            try
            {
                abstractElevator.ResumeOperations(); 
            }
            catch (Exception ex)
            {
                MainWindow.WriteDebug("RS232-port niet geselecteerd. "+ex.Message);
            }
        }
        #endregion

        #region Tabs - Storage buttons

        //in iedere tab, zijn eigen data weg schrijven
        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            renewCurrentTab();
        }
        private void renewCurrentTab()
        {
            lock (txtArrivedAt)
            {
                try
                {
                    if (tabControl1.SelectedIndex == 0)
                    {
                        aantalKeer();
                        noodstopcount();
                    }
                    if (tabControl1.SelectedIndex == 1)
                    {
                        txtArrivedAt.Text = "";

                        foreach (LoggingEntry item in st.GetLog("arrived at"))
                        {
                            txtArrivedAt.Text += "\nDe lift is ooit aan gekomen bij verdieping " + item.message + ", op " + item.timestamp;
                        }
                    }
                    if (tabControl1.SelectedIndex == 2)
                    {
                        txtMovingTo.Text = "";

                        foreach (LoggingEntry item in st.GetLog("moving to"))
                        {
                            txtMovingTo.Text += "\nDe lift ging naar verdieping " + item.message + ", op " + item.timestamp;
                        }
                    }
                    if (tabControl1.SelectedIndex == 3)
                    {
                        txtEmergency.Text = "";

                        foreach (LoggingEntry item in st.GetLog("emergency break"))
                        {
                            txtEmergency.Text += "\nDe Emergency Break is gebruikt op " + item.timestamp;
                        }
                    }
                    if (tabControl1.SelectedIndex == 4)
                    {
                        txtGoTo.Text = "";

                        foreach (LoggingEntry item in st.GetLog("go to"))
                        {
                            txtGoTo.Text += "\nDe lift heeft verdieping " + item.message + " als Go To aanvraag gekregen op " + item.timestamp;
                        }
                    }
                    if (tabControl1.SelectedIndex == 5)
                    {
                        txtResume.Text = "";

                        foreach (LoggingEntry item in st.GetLog("resume operations"))
                        {
                            txtResume.Text += "\nDe lift heeft resume operations aanvraag gekregen op " + item.timestamp;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MainWindow.WriteDebug(ex.Message);
                }


            }
        }
        private void aantalKeer()
        {
            int keer1 = 0;
            int keer2 = 0;
            int keer3 = 0;
            int keer4 = 0;

            foreach (LoggingEntry item in st.GetLog("arrived at"))
            {
                switch (item.message)
                {
                    case "0":
                        keer1++;
                        break;
                    case "1":
                        keer2++;
                        break;
                    case "2":
                        keer3++;
                        break;
                    case "3":
                        keer4++;
                        break;
                }
            }

            lbl_keer1.Text = keer1.ToString();
            lbl_keer2.Text = keer2.ToString();
            lbl_keer3.Text = keer3.ToString();
            lbl_keer4.Text = keer4.ToString();

            if (keer1 > keer2)
            {
                if (keer1 > keer3)
                {
                    if (keer1 > keer4)
                    {
                        lbl_meestBezocht.Text = "De begane grond is het meest bezocht.";
                    }
                    else
                    {
                        lbl_meestBezocht.Text = "Verdieping 3 is het meest bezocht.";
                    }
                }
                else
                {
                    if (keer3 > keer4)
                    {
                        lbl_meestBezocht.Text = "Verdieping 2 is het meest bezocht.";
                    }
                    else
                    {
                        lbl_meestBezocht.Text = "Verdieping 3 is het meest bezocht.";
                    }
                }
            }
            else
            {
                if (keer2 > keer3)
                {
                    if (keer2 > keer4)
                    {
                        lbl_meestBezocht.Text = "Verdieping 1 is het meest bezocht.";
                    }
                    else
                    {
                        lbl_meestBezocht.Text = "Verdieping 3 is het meest bezocht.";
                    }
                }
                else
                {
                    if (keer3 > keer4)
                    {
                        lbl_meestBezocht.Text = "Verdieping 2 is het meest bezocht.";
                    }
                    else
                    {
                        lbl_meestBezocht.Text = "Verdieping 3 is het meest bezocht.";
                    }
                }
            }
        }

        private void noodstopcount()
        {
            int keernoodstop = 0;

            foreach (LoggingEntry item in st.GetLog("emergency break"))
            {
                keernoodstop++;
            }

            lbl_noodstop.Text = keernoodstop.ToString();
        }

        //Statistics labels
        /* 
         * lbl_keer1
         * lbl_keer2
         * lbl_keer3
         * lbl_keer4
         * lbl_noodstop
         * lbl_meestBezocht
         */

        #endregion

        #region Twitter Button + Send Message Handler
        private void btnTwitterAuthenticate_Click(object sender, EventArgs e)
        {
            if (tw.setPin(txtTwitterPin.Text))
            {
                lblTwitterStatus.Text = "Succesfully authenticated.";
                MainWindow.WriteDebug("Authenticated on Twitter.");
                txtTwitterPin.Enabled = false;
                btnTwitterAuthenticate.Enabled = false;
            }
            else
            {
                tw = new TwitterLib.Twitter();
            }
        }

        private void SendTwitterMessage(object feedback, ElevatorFeedbackEventArgs message)
        {
            //MessageBox.Show("gonna send a tweet: " + message.message);

            try
            {
                tw.SendTweet(message.message);
                //MainWindow.WriteDebug(message.message);
            }
            catch (Exception e)
            {
                MainWindow.WriteDebug(e.Message);
            }
        }

        private void SendRS232Message(object feedback, TwitterEventArgs message)
        {
            //MessageBox.Show("received a message: " + message.message);

            switch (message.message)
            {
                case "1":
                    abstractElevator.GoTo(1);
                    break;
                case "2":
                    abstractElevator.GoTo(2);
                    break;
                case "3":
                    abstractElevator.GoTo(3);
                    break;
                case "4":
                    abstractElevator.GoTo(4);
                    break;
                case "r":
                    abstractElevator.ResumeOperations();
                    break;
                case "e":
                    abstractElevator.CallEmergency();
                    break;
            }
        }

        #endregion

    }
}
